<?php

namespace common\filters;

use Yii;
use yii\helpers\ArrayHelper;
use yii\helpers\StringHelper;
use yii\filters\auth\HttpBearerAuth;
use yii\web\UnauthorizedHttpException;

/**
 * HttpBearerAuth is an action filter that supports the authentication method based on HTTP Bearer token.
 *
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class AppBearerAuth extends HttpBearerAuth {

    /**
     * @var integer the Http authentication user's primary key ID.
     */
    public $uid = 0;

    /**
     * @var integer the Http authentication user's primary key ID.
     */
    public $build = false;

    /**
     * @var string the HTTP authentication realm
     */
    public $filterAccessToken = true;

    /**
     * @var array the HTTP authentication realm
     */
    public $accessAllows = [];

    /**
     * @var string the HTTP authentication token
     */
    public $identityClass = '';

    /**
     * @inheritdoc
     */
    public function beforeAction($action) {
        $request = $this->request ?: Yii::$app->getRequest();
        $response = $this->response ?: Yii::$app->getResponse();
        $user = $this->user ?: Yii::$app->getUser();
        if ($this->identityClass) {
            $user = new $this->identityClass;
        }
//        if ($request->isOptions) {
//            $allowOrigins = ArrayHelper::getValue(Yii::$app->params, 'crossDomains', []);
//            if (!$request->origin || in_array($request->origin, $allowOrigins)) {
//                return true;
//            }
//            return false;
//        }
        $this->build = $action->controller->build;

        try {
            $identity = $this->authenticate($user, $request, $response);
//            if (YII_DEBUG && YII_ENV_DEV && $identity === null) {
//                $debugClass = $this->identityClass;
//                $identity = $debugClass::findOne(1);
//            }
            if ($identity !== null) {
                $this->bindAuthenticate($identity);
                $this->bindVersion($response);
                return true;
            }
            $this->challenge($response);
            $this->handleFailure($response);
        } catch (UnauthorizedHttpException $e) {
            Yii::error($e->getMessage(), __METHOD__);
            if ($this->isOptional($action) || $this->isPublicRoute($action) || $this->filterAccessToken === false) {
                return true;
            }
            throw $e;
        }
        return false;
    }

    /**
     * @inheritdoc
     */
    public function isPublicRoute($action) {
        $id = $action->getUniqueId();
        foreach ($this->accessAllows as $pattern) {
            if (StringHelper::matchWildcard($pattern, $id)) {
                return true;
            }
        }
        return false;
    }

    /**
     * @inheritdoc
     */
    public function bindAuthenticate($identity) {
        $this->uid = $identity->id;
        $this->user = $identity;
    }

    /**
     * @param yii\web\Request $response Description
     * @inheritdoc
     */
    public function bindVersion($response) {
        $response->getHeaders()->set('Access-Control-Expose-Headers', 'Build');
        $response->getHeaders()->set('Build', $this->build);
    }

}
